<template>
	<el-dialog width="40%" :title="form.storeId ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
		<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
			<el-row :gutter="24">
				<el-col :span="24" class="mb20">
					<el-form-item label="类型" prop="storeType">
						<el-select v-model="form.storeType" placeholder="请选择类型">
							<el-option :label="item.label" :value="item.value" v-for="(item, index) in embed_store_type" :key="index"></el-option>
						</el-select>
					</el-form-item>
				</el-col>

				<el-col :span="24" class="mb20">
					<el-form-item label="名称" prop="name">
						<el-input v-model="form.name" placeholder="请输入名称" />
					</el-form-item>
				</el-col>

				<el-col :span="24" class="mb20" v-if="form.storeType !== 'qdrant' && form.storeType !== 'redis' && form.storeType !== 'pgvector' && form.storeType !== 'neo4j'">
					<el-form-item label="URI" prop="uri">
						<el-input v-model="form.uri" placeholder="请输入链接地址" />
					</el-form-item>
				</el-col>

				<el-col :span="24" class="mb20" v-if="form.storeType === 'qdrant' || form.storeType === 'redis' || form.storeType === 'pgvector'">
					<el-form-item label="Host" prop="host">
						<el-input v-model="form.host" placeholder="请输入Host" />
					</el-form-item>
				</el-col>

				<el-col :span="24" class="mb20" v-if="form.storeType === 'qdrant' || form.storeType === 'redis' || form.storeType === 'pgvector'">
					<el-form-item label="端口" prop="port">
						<el-input-number v-model="form.port" placeholder="请输入端口" />
					</el-form-item>
				</el-col>

				<!-- Neo4j URI 配置 -->
				<el-col :span="24" class="mb20" v-if="form.storeType === 'neo4j'">
					<el-form-item label="URI" prop="uri">
						<el-input v-model="form.uri" placeholder="请输入URI地址" />
					</el-form-item>
				</el-col>

				<el-col :span="24" class="mb20" v-if="form.storeType !== 'pgvector' && form.storeType !== 'neo4j'">
					<el-form-item label="密钥" prop="apiKey">
						<el-input v-model="form.apiKey" placeholder="请输入密钥" />
					</el-form-item>
				</el-col>

				<el-col :span="24" class="mb20" v-if="form.storeType === 'milvus'">
					<el-form-item label="数据库" prop="extData">
						<el-input v-model="form.extData" placeholder="请输入数据库" />
					</el-form-item>
				</el-col>

				<!-- PgVector 特有配置 -->
				<template v-if="form.storeType === 'pgvector'">
					<el-col :span="24" class="mb20">
						<el-form-item label="用户名" prop="pgUsername">
							<el-input v-model="form.pgUsername" placeholder="请输入用户名" />
						</el-form-item>
					</el-col>

					<el-col :span="24" class="mb20">
						<el-form-item label="密码" prop="pgPassword">
							<el-input v-model="form.pgPassword" type="password" placeholder="请输入密码" show-password />
						</el-form-item>
					</el-col>

					<el-col :span="24" class="mb20">
						<el-form-item label="数据库" prop="pgDatabase">
							<el-input v-model="form.pgDatabase" placeholder="请输入数据库名" />
						</el-form-item>
					</el-col>

					<el-col :span="24" class="mb20">
						<el-form-item label="维度" prop="pgDimension">
							<el-input-number v-model="form.pgDimension" :min="1" :max="4096" placeholder="请输入向量维度" />
						</el-form-item>
					</el-col>
				</template>

				<!-- Neo4j 特有配置 -->
				<template v-if="form.storeType === 'neo4j'">
					<el-col :span="24" class="mb20">
						<el-form-item label="用户名" prop="neo4jUsername">
							<el-input v-model="form.neo4jUsername" placeholder="请输入用户名" />
						</el-form-item>
					</el-col>

					<el-col :span="24" class="mb20">
						<el-form-item label="密码" prop="neo4jPassword">
							<el-input v-model="form.neo4jPassword" type="password" placeholder="请输入密码" show-password />
						</el-form-item>
					</el-col>

					<el-col :span="24" class="mb20">
						<el-form-item label="数据库" prop="neo4jDatabase">
							<el-input v-model="form.neo4jDatabase" placeholder="请输入数据库名" />
						</el-form-item>
					</el-col>

					<el-col :span="24" class="mb20">
						<el-form-item label="维度" prop="neo4jDimension">
							<el-input-number v-model="form.neo4jDimension" :min="1" :max="4096" placeholder="请输入向量维度" />
						</el-form-item>
					</el-col>
				</template>

				<el-col :span="24" class="mb20">
					<el-form-item prop="useTls" v-if="form.storeType === 'qdrant'">
						<template #label> TLS<tip content="HTTPS安全认证" /> </template>
						<el-radio-group v-model="form.useTls">
							<el-radio :key="index" :label="item.value" border v-for="(item, index) in yes_no_type">{{ item.label }} </el-radio>
						</el-radio-group>
					</el-form-item>
				</el-col>
			</el-row>
		</el-form>
		<template #footer>
			<span class="dialog-footer">
				<el-button @click="visible = false">取消</el-button>
				<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
			</span>
		</template>
	</el-dialog>
</template>

<script setup lang="ts" name="AiEmbedStoreDialog">
import { useDict } from '/@/hooks/dict';
import { useMessage } from '/@/hooks/message';
import { getObj, addObj, putObj, validateExist } from '/@/api/knowledge/aiEmbedStore';
const emit = defineEmits(['refresh']);

// 定义变量内容
const dataFormRef = ref();
const visible = ref(false);
const loading = ref(false);
// 定义字典
const { embed_store_type, yes_no_type } = useDict('embed_store_type', 'yes_no_type');

// 提交表单数据
const form = reactive({
	storeId: '',
	name: '',
	storeType: 'milvus',
	host: '127.0.0.1',
	port: 6334,
	uri: 'http://127.0.0.1:19530',
	apiKey: '',
	extData: 'default',
	useTls: '0',
	// PgVector 特有字段
	pgUsername: 'postgres',
	pgPassword: 'postgres',
	pgDatabase: 'database',
	pgDimension: 4096,
	// Neo4j 特有字段
	neo4jUsername: 'neo4j',
	neo4jPassword: 'neo4jneo4j',
	neo4jDatabase: 'neo4j',
	neo4jDimension: 4096,
});

// 监听 storeType 变化，设置默认端口和URI
watch(
	() => form.storeType,
	(newType) => {
		if (newType === 'pgvector') {
			form.port = 5432;
		} else if (newType === 'qdrant') {
			form.port = 6334;
		} else if (newType === 'redis') {
			form.port = 6379;
		} else if (newType === 'neo4j') {
			form.uri = 'neo4j://localhost:7687';
		}
	}
);

// 定义校验规则
const dataRules = ref({
	name: [
		{ required: true, message: '名称不能为空', trigger: 'blur' },
		{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
		{
			validator: (rule: any, value: any, callback: any) => {
				validateExist(rule, value, callback, form.storeId !== '');
			},
			trigger: 'blur',
		},
	],
	storeType: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
	host: [
		{ required: true, message: 'Host不能为空', trigger: 'blur' },
		{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
	],
	port: [
		{ required: true, message: '端口不能为空', trigger: 'blur' },
		{ type: 'number', max: 65535, message: '端口不能超过65535', trigger: 'blur' },
	],
	uri: [
		{ required: true, message: '地址不能为空', trigger: 'blur' },
		{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
		{
			validator: (rule: any, value: any, callback: any) => {
				// URI变化时，重新验证数据库字段
				nextTick(() => {
					if (dataFormRef.value) {
						dataFormRef.value.validateField('extData');
					}
				});
				callback();
			},
			trigger: 'blur',
		},
	],
	extData: [
		{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
		{
			validator: (rule: any, value: any, callback: any) => {
				// 检查URI是否包含.zilliz.com.cn（在线服务）
				if (form.uri && form.uri.includes('.zilliz.com.cn')) {
					if (!value) {
						callback(new Error('使用Zilliz在线服务时，数据库字段不能为空'));
						return;
					}
					// 检查数据库字段格式是否为 db_xxxx
					const dbPattern = /^db_\w+$/;
					if (!dbPattern.test(value)) {
						callback(new Error('使用Zilliz在线服务时，数据库字段必须是 db_id 的形式'));
						return;
					}
				}
				callback();
			},
			trigger: 'blur',
		},
	],
	// PgVector 校验规则
	pgUsername: [
		{ required: true, message: '用户名不能为空', trigger: 'blur' },
		{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
	],
	pgPassword: [
		{ required: true, message: '密码不能为空', trigger: 'blur' },
		{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
	],
	pgDatabase: [
		{ required: true, message: '数据库名不能为空', trigger: 'blur' },
		{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
	],
	pgDimension: [
		{ required: true, message: '维度不能为空', trigger: 'blur' },
		{ type: 'number', min: 1, max: 4096, message: '维度必须在1-4096之间', trigger: 'blur' },
	],
	// Neo4j 校验规则
	neo4jUsername: [
		{ required: true, message: '用户名不能为空', trigger: 'blur' },
		{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
	],
	neo4jPassword: [
		{ required: true, message: '密码不能为空', trigger: 'blur' },
		{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
	],
	neo4jDatabase: [
		{ required: true, message: '数据库名不能为空', trigger: 'blur' },
		{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
	],
	neo4jDimension: [
		{ required: true, message: '维度不能为空', trigger: 'blur' },
		{ type: 'number', min: 1, max: 4096, message: '维度必须在1-4096之间', trigger: 'blur' },
	],
});

// 打开弹窗
const openDialog = (id: string) => {
	visible.value = true;
	form.storeId = '';
	form.extData = '';

	// 重置表单数据
	nextTick(() => {
		dataFormRef.value?.resetFields();
	});

	// 获取aiEmbedStore信息
	if (id) {
		form.storeId = id;
		getaiEmbedStoreData(id);
	}
};

// 提交
const onSubmit = async () => {
	const valid = await dataFormRef.value.validate().catch(() => {});
	if (!valid) return false;

	try {
		loading.value = true;
		// 修复TypeScript错误：正确处理apiKey的类型
		const submitForm = { ...form };
		
		// 处理 pgvector 类型的特殊逻辑
		if (form.storeType === 'pgvector') {
			// 将 pgvector 的配置信息存储到 extData 中
			const pgConfig = {
				username: form.pgUsername,
				password: form.pgPassword,
				database: form.pgDatabase,
				dimension: form.pgDimension,
			};
			submitForm.extData = JSON.stringify(pgConfig);
			
			// 清空不需要的字段
			submitForm.apiKey = '';
		} else if (form.storeType === 'neo4j') {
			// 将 neo4j 的配置信息存储到 extData 中
			const neo4jConfig = {
				username: form.neo4jUsername,
				password: form.neo4jPassword,
				database: form.neo4jDatabase,
				dimension: form.neo4jDimension,
			};
			submitForm.extData = JSON.stringify(neo4jConfig);
			
			// 清空不需要的字段
			submitForm.apiKey = '';
		} else {
			// 处理其他类型的 apiKey
			if (submitForm.apiKey?.includes('***')) {
				submitForm.apiKey = '';
			}
		}
		
		// 移除 pgvector 和 neo4j 特有的临时字段
		delete (submitForm as any).pgUsername;
		delete (submitForm as any).pgPassword;
		delete (submitForm as any).pgDatabase;
		delete (submitForm as any).pgDimension;
		delete (submitForm as any).neo4jUsername;
		delete (submitForm as any).neo4jPassword;
		delete (submitForm as any).neo4jDatabase;
		delete (submitForm as any).neo4jDimension;
		
		form.storeId ? await putObj(submitForm) : await addObj(submitForm);
		useMessage().success(form.storeId ? '修改成功' : '添加成功');
		visible.value = false;
		emit('refresh');
	} catch (err: any) {
		useMessage().error(err.msg);
	} finally {
		loading.value = false;
	}
};

// 初始化表单数据
const getaiEmbedStoreData = (id: string) => {
	// 获取数据
	loading.value = true;
	getObj({ storeId: id })
		.then((res: any) => {
			Object.assign(form, res.data);
			
			// 如果是 pgvector 类型，解析 extData 中的配置
			if (form.storeType === 'pgvector' && form.extData) {
				try {
					const pgConfig = JSON.parse(form.extData);
					form.pgUsername = pgConfig.username || 'postgres';
					form.pgPassword = pgConfig.password || 'postgres';
					form.pgDatabase = pgConfig.database || 'database';
					form.pgDimension = pgConfig.dimension || 4096;
				} catch (e) {
					// 解析失败时使用默认值
					form.pgUsername = 'postgres';
					form.pgPassword = 'postgres';
					form.pgDatabase = 'database';
					form.pgDimension = 4096;
				}
			}
			
			// 如果是 neo4j 类型，解析 extData 中的配置
			if (form.storeType === 'neo4j' && form.extData) {
				try {
					const neo4jConfig = JSON.parse(form.extData);
					form.neo4jUsername = neo4jConfig.username || 'neo4j';
					form.neo4jPassword = neo4jConfig.password || 'neo4j';
					form.neo4jDatabase = neo4jConfig.database || 'neo4j';
					form.neo4jDimension = neo4jConfig.dimension || 4096;
				} catch (e) {
					// 解析失败时使用默认值
					form.neo4jUsername = 'neo4j';
					form.neo4jPassword = 'neo4j';
					form.neo4jDatabase = 'neo4j';
					form.neo4jDimension = 4096;
				}
			}
		})
		.finally(() => {
			loading.value = false;
		});
};

// 暴露变量
defineExpose({
	openDialog,
});
</script>
